<?php
/**
* @software         [JiJinCMS]
* @author           [上海集锦信息科技有限公司]
* @website          [http://www.jijinweb.com]
* @email            [sunny@jijinweb.com]
**/
namespace app\admin\model;
use think\Model;
use think\facade\Db;
class TemplateModel extends Model{
    protected $name = 'template';
    protected $pk = 'template_id';
    public $content;//模板内容
    const templatePath='data/templateFile/';//模板文件所在路径
    //生成template文件
    public function makeTemplateFile($template_id){
        $template_r=$this->find($template_id);
        $this->content=$template_r["content"];
        $this->replaceTemplate();
        //如果模板类型是公共模板的话文件名以myvar的值命名
        if($template_r["type"]=="public"){
            file_put_contents(base_path().self::templatePath.$template_r["myvar"].".html",$this->content);
        }else{
            file_put_contents(base_path().self::templatePath.$template_id.".html",$this->content);
        }
    }//
    //删除模板文件
    public function deleteTemplateFile($template_id){
        @unlink(base_path().self::templatePath.$template_id.".html");
    }
    /*
     * 模板替换
     */
    public function replaceTemplate(){
        //转码
        $this->content=htmlspecialchars_decode($this->content);
        //公共模板替换
        $this->content=  preg_replace("/\{include \"(.+?)\"}/","{include file='".base_path().self::templatePath."\\1'/}",$this->content);
        //标签替换
        $this->repList();//list标签替换
        $this->repInfo();//info标签替换
        $this->repCat();//cat标签替换
        $this->repTable();//table标签替换
        $this->repNav();//nav标签替换
        $this->repFilter();//repFilter标签替换
        $this->repFilter2();//repFilter2标签替换
        $this->repOrder();//repOrder标签替换
        $this->repLink();//repLink标签替换
        $this->repAd();//repAd标签替换
    }
    //替换list标签
    public function repList(){
        $this->content=str_replace('{/list}','<?php } ?>',$this->content);
        preg_match_all("/{list([\S\s]+)}/U",$this->content,$result);
        $this->parsingLabel($result,"listFun");
    }
    //替换cat标签
    public function repCat(){
        $this->content=str_replace('{/cat}','<?php } ?>',$this->content);
        preg_match_all("/{cat([\S\s]*)}/U",$this->content,$result);
        $this->parsingLabel($result,"catFun");
    }    
    //替换info标签
    public function repInfo(){
        $this->content=str_replace('{/info}','<?php } ?>',$this->content);
        preg_match_all("/{info([\S\s]+)}/U",$this->content,$result);
        $this->parsingLabel($result,"infoFun");
    }    
    //替换table标签
    public function repTable(){
        $this->content=str_replace('{/table}','<?php } ?>',$this->content);
        preg_match_all("/{table([\S\s]+)}/U",$this->content,$result);
        $this->parsingLabel($result,"tableFun");
    }
    //替换nav标签
    public function repNav(){
        $this->content=str_replace('{/nav}','',$this->content);
        //匹配不带参数的
        $this->content=preg_replace("/{nav(\s*)}/",'<?php echo navFun();?>',$this->content);
        preg_match_all("/{nav([\S\s]+)}/U",$this->content,$result);
        $this->parsingLabel2($result,"navFun");
    }
    //
    public function repFilter(){
        $this->content=str_replace('{/filter}','',$this->content);
        preg_match_all("/{filter ([\S\s]+)}/U",$this->content,$result);
        $this->parsingLabel2($result,"filterFun");
    }
    public function repFilter2(){
        $this->content=str_replace('{/filter2}','',$this->content);
        preg_match_all("/{filter2 ([\S\s]+)}/U",$this->content,$result);
        $this->parsingFilter2Label($result,"filter2Fun");
    }
    public function repOrder(){
        $this->content=str_replace('{/order}','',$this->content);
        preg_match_all("/{order ([\S\s]+)}/U",$this->content,$result);
        $this->parsingFilter2Label($result,"orderFun");
    }    
    public function repLink(){
        $this->content=str_replace('{/link}','<?php } ?>',$this->content);
        preg_match_all("/{link([\S\s]*)}/U",$this->content,$result);
        $this->parsingLabel($result,"linkFun");
    }  
    public function repAd(){
        $this->content=str_replace('{/ad}','<?php } ?>',$this->content);
        preg_match_all("/{ad([\S\s]*)}/U",$this->content,$result);
        $this->parsingLabel($result,"adFun");
    }     
    //解析标签语法
    private function parsingLabel(array $result,string $funName){
        foreach($result[1] as $k1=>$v1){
            $v1=str_replace(PHP_EOL," ",$v1);
            //条件提取
            preg_match_all("/(\S+)(<like>|<not like>|<in>|>=|<=|=|>|<|<>)\"(.*)\" /U"," ".$v1." ",$result2);
            $where=[];
            $config=array();
            foreach($result2[0] as $k2=>$v2){
                $field=trim($result2[1][$k2]);
                $expression=trim($result2[2][$k2]);
                //过滤<like|not like等标签>
                $expression=preg_replace("/<(.+)>/","\\1",$expression);
                $value=trim($result2[3][$k2]);
                if(preg_match("/^_/",$field)){
                    //重新解释true或者false
                    if($value=="false"){
                        $value=false;
                    }elseif($value=="true"){
                        $value=true;
                    }
                    $config[$field]=$value;
                }else{
                    //如果是like查询，要加or参数，这样当value是数组的形式的时候这些多个值之间是or，否则查询不出来数据
                    if($expression=="like"){
                        $where[]=[$field,$expression,$value,"OR"];
                    }else{
                        $where[]=[$field,$expression,$value];
                    }
                    
                }
            }
            $where = var_export($where,true);
            //key变量名
            $keyName=$config["_key"]?trim($config["_key"],"$"):"key";
            //变量名
            $vName=$config["_v"]?trim($config["_v"],"$"):"v";    
            //是否开启分页
            $_page_on=$config["_page_on"];
            if($_page_on){
                $_page_list_rows=intval($config["_page_list_rows"])?intval($config["_page_list_rows"]):10;
                $_page_query=$config["_page_query"]?$config["_page_query"]:"";
                $_page_display_var=$config["_page_display_var"]?trim($config["_page_display_var"],"$"):"page";
                $_page_url_var=$config["_page_url_var"]?$config["_page_url_var"]:"label_page";
            }
            $config = var_export($config,true);
            //随机生成一个变更名，防止和系统的变量冲突
            $rand_var='$var_name_'.make_random(16);
            
            $config =preg_replace("/\'\\$(.+)\',/","\"$\\1\",",$config);//单引号转双引号
            $where  =preg_replace("/\'\\$(.+)\',/","\"$\\1\",",$where);//单引号转双引号
            //将config和where中的变量两边的单引号或者双引号去掉
            $config=preg_replace("/\'\\$(.+)\',/","$\\1,",$config);//单引号
            $config=preg_replace("/\"\\$(.+)\",/","$\\1,",$config);//双引号
            $where=preg_replace("/\'\\$(.+)\',/","$\\1,",$where);//单引号
            $where=preg_replace("/\"\\$(.+)\",/","$\\1,",$where);//双引号
            //将中$selft[\"catid\"] $selft[\'catid\']替换为$selft["catid"] $selft['catid']
            $config =preg_replace("/\[\\\'(\w+)\\\'\]/","['\\1']",$config);
            $config =preg_replace("/\[\\\"(\w+)\\\"\]/","['\\1']",$config);
            $where  =preg_replace("/\[\\\'(\w+)\\\'\]/","['\\1']",$where);
            $where  =preg_replace("/\[\\\"(\w+)\\\"\]/","['\\1']",$where);
            //模板代码生成
            $label_str='<?php '.$rand_var.'='.$funName.'('.$config.','.$where.');';
            if($_page_on){
                $label_str.='$'.$_page_display_var.'='.$rand_var.'["page"]; ';
            }
            $label_str.='foreach('.$rand_var.'["data"] as $'.$keyName.'=>$'.$vName.'){  ?>';
            $this->content=str_replace($result[0][$k1],$label_str,$this->content);
        }
    }
    //解析标签语法2 不区分config和where字段，将所有参数都放到一个字段里面,结果输出函数
    private function parsingLabel2(array $result,string $funName){
        foreach($result[1] as $k1=>$v1){
            $v1=str_replace(PHP_EOL," ",$v1);
            //条件提取
            preg_match_all("/(.+)=\"(.+)\" /U"," ".$v1." ",$result2);
            $where=[];
            $config=array();
            foreach($result2[0] as $k2=>$v2){
                $field=trim($result2[1][$k2]);
                $value=trim($result2[2][$k2]);
                $where[$field]=$value;
            }
            $where = var_export($where,true);
            //模板代码生成
            $label_str='<?php echo '.$funName.'('.$where.');?>';
            $this->content=str_replace($result[0][$k1],$label_str,$this->content);
        }
    }
    //filter2标签解析
    private function parsingFilter2Label(array $result,string $funName){
        foreach($result[1] as $k1=>$v1){
            $v1=str_replace(PHP_EOL," ",$v1);
            //条件提取
            preg_match_all("/(.+)=\"(.+)\" /U"," ".$v1." ",$result2);
            $where=[];
            $config=array();
            foreach($result2[0] as $k2=>$v2){
                $field=trim($result2[1][$k2]);
                $value=trim($result2[2][$k2]);
                $where[$field]=$value;
            }
            $where = var_export($where,true);
            //模板代码生成
            $label_str='<?php echo '.$funName.'('.$where.',$where);?>';
            $this->content=str_replace($result[0][$k1],$label_str,$this->content);
        }
    }
}
